home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-06-15 | 51.9 KB | 1,034 lines | [TEXT/pdos] |
- Apple II
- File Type Notes
- _____________________________________________________________________________
- Developer Technical Support
-
-
- File Type: $54 (84)
- Auxiliary Type: $DD3E
-
- Full Name: Medley Desktop Publishing Document
- Short Name: Medley Document
-
- Written by: Matt Deatherage & Eric Soldan May 1989
-
- Files of this type and auxiliary type contain documents for Medley(TM).
- _____________________________________________________________________________
-
- Medley is a WYSIWYG application that integrates word processing, paint, and
- page layout programs, with the addition of a spelling checker and thesaurus.
- The page layout function supports various shapes for art and text areas. Text
- automatically wraps around or within these areas, including irregularly shaped
- regions. The word processor is full-featured, as is the paint program. The
- dictionary has 80,000 words.
-
- For more information on Medley, contact:
-
- Milliken Publishing Company
- 1100 Research Blvd.
- St. Louis, MO 63132
- Attention: Medley Technical Support
- (314) 991-4220
-
- The Medley file format is copyrighted (C) 1988 by Milliken Publishing Company
- and is printed here with permission.
-
- Definitions
-
- The following definition is used in this document in addition to those defined
- for all Apple II file types:
-
- C String A series of ASCII bytes terminated with a byte of $00.
- There is no count byte at the beginning, as is the case for
- the String type (also referred to as a "Pascal string").
-
-
- File Structure
-
- Medley files are basically standard, single-linked tree structures. There is
- a single object at the top of the tree, and other objects may branch off this
- parent object. Each child object is linked to the parent by a pointer to the
- child contained within the parent object. A non-standard thing about the
- Medley tree structure is that some objects may have regions or polygons
- associated with them. The handles to these objects are stored in the parent
- object when in memory, but on disk these handles are quite meaningless.
- Because of this difference, the regions or polygons are simply appended to the
- parent object itself when written to disk. The size of the region or polygon
- is added to the size of the parent object, giving an aggregate size for the
- complex object on disk.
-
- The file is written to disk in an order based on a simple tree-walking
- algorithm. This algorithm starts with the highest parent object and writes it
- to disk. The parent object is checked for child objects. If one exists, it
- is written to disk, and then it is checked for child objects. This tree-
- walking continues until an object runs out of children. When that occurs,
- Medley backs up one tree level, writes the next child object to disk, and
- scans it for children. This method continues until all objects are written to
- disk.
-
- For example, if a parent object named A had two child objects named B and C,
- where B had children E and F, and C had children G and H, the objects would be
- written to disk in the following order: A, B, D, E, C, F, G. Figure 1
- illustrates this structure.
- _________
- | |
- | A |
- |_________|
- |---------------|---------------|
- ____|____ ____|____
- | | | |
- | B | | C |
- |_________| |_________|
- |-------|-------|---------------|-------|-------|
- ____|____ ____|____ ____|____ ____|____
- | | | | | | | |
- | D | | E | | F | | G |
- |_________| |_________| |_________| |_________|
-
- Figure 1-Example of Parent and Child Tree Structure
-
- Some Medley objects, when in memory, have handles to other objects (such as
- regions or polygons) in them. Since handles are meaningless on disk, Medley
- stores these complex objects in an aggregate form by writing the contents of
- each associated handle to disk following the regular object.
-
- The Objects and Their Formats
-
- All objects have a common 13-byte header, which is as follows:
-
- type (+000) Byte The type of the object. Possible
- values are:
- 0 = Null Object (never saved to disk)
- 1 = Root Object (never saved to disk)
- 2 = File Object
- 3 = Page Object
- 4 = Paragraph Object
- 5 = Area Object
- 6 = Art Object
- 10 = Document Dictionary Object.
- Objects 7, 8 and 9 are for posting
- undo events. Since these are not
- saved to disk, they are irrelevant
- for the file format.
- numChildren (+001) Word The number of children for this
- object. Children of the children
- are not included.
- endData (+003) Long The size of this object on the
- disk, not counting associated
- handles (such as regions and
- polygons).
- reserved (+007) Long Reserved; set to zero when
- creating files.
- objRefNum (+011) Word The reference number of this
- object, generally zero.
-
- Each object has the header listed above followed by object-specific data. For
- this reason, the description of each object will start with offset +013 (the
- byte following the header).
-
- The File Object
-
- rect (+013) 4 Words Standard QuickDraw II rectangle,
- giving the boundary rectangle for
- the entire file.
- pathName (+021) 129 Bytes Class zero pathname for the
- file on disk (used by the save
- command).
- saved (+150) Byte This byte is 1 if no changes have
- been made to the file since the last
- save.
- windowPtr (+151) Long Pointer to the window for this
- file. When creating files, set to
- zero.
- wndwNameIndx (+155) Byte Index into table of window
- names. Set to zero when creating
- files
- windowOrigin (+156) 2 Words QuickDraw II point
- representing the global origin of
- this file's window.
- windowSize.h (+160) Word Height of window in pixels.
- Add to top edge of window to get
- bottom edge of window.
- windowSize.v (+162) Word Height of window in pixels.
- Add to left of window to get right
- edge of window.
- COrigin (+164) Long QuickDraw II point representing the
- scroll bar origin of this file's
- window. When creating files, set
- this to whatever origin you wish
- Medley to display. Make sure that
- the coordinate is valid.
- editHndl (+168) Long Handle to the paragraph containing
- the cursor. This is converted to a
- child number on disk, since handles
- on disk are meaningless.
- editOffset (+172) Word Offset to the cursor within the
- paragraph pointed to by editHndl.
- cursor (+174) 4 Words Standard QuickDraw II rectangle,
- giving the rectangle used for the
- insert cursor. This can be set to a
- null rectangle when creating files,
- and will be calculated when the file
- is loaded.
- showAllBorders (+182) Byte If this is set to one, then
- all area borders will display,
- regardless of each area's border
- display setting.
- updateRect (+183) 4 Words Standard QuickDraw II
- rectangle used for posting specific
- updates for the interruptible word
- processor. When creating files, set
- this to a null rectangle.
- topMrgn (+191) Fixed The top margin in inches.
- bottomMrgn (+195) Fixed The bottom margin in inches.
- leftMrgn (+199) Fixed The left margin in inches.
- rightMrgn (+203) Fixed The right margin in inches.
- gutterMrgn (+207) Fixed The gutter margin in inches.
- pageWidth (+211) Fixed The width of the page in inches.
- pageHeight (+215) Fixed The height of the page in
- inches.
- selectPage (+219) Word The active page for area
- editing.
- numSelected (+221) Word The number of areas currently
- selected by the user.
- sizingDot (+223) Word The sizing dot number of an area
- that was last clicked. This sizing
- dot will be used as the current
- sizing dot when the arrows are used
- to size an area.
- effectivePage (+225) Word The page number of the page
- the user was effectively editing.
- This is different from selectPage
- when the user was editing global
- areas at save time, for global areas
- are treated as on page zero.
- printRecord (+227) 140 Bytes A standard IIGS Print
- Manager print record; the one in use
- for this document at save time.
- This field can be undefined, if the
- printRecordDefined field is zero.
- interruptMode (+367) Word Currently undocumented. (Set
- to zero.)
- editScroll (+369) Byte Currently undocumented. (Set to
- zero.)
- firstHndl (+370) Long Handle where wrap-around regions
- should actually start; i.e., where
- an update is needed. When creating
- files, set this to zero.
- firstMrn (+374) Word MiniRect number (line number of
- paragraph) where wrap-around regions
- should actually start; i.e., where
- an update is needed. When creating
- files, set this to zero.
- selectMode (+376) Word Some text is selected if this is
- 1. Each paragraph will indicate the
- range of characters selected within
- that paragraph. This allows the
- screen update routine to quickly
- determine which characters in a
- paragraph should be drawn selected.
- showPgphMarks (+378) Byte Indicates whether paragraph
- marks are currently being shown.
- showSpaces (+379) Byte Indicates whether spaces are
- shown with marks and tabs are shown
- with arrows.
- showMoveChangeInfo
- (+380) Byte Indicates whether the Move/Change window
- is active.
- moveChangeInfoRect
- (+381) 4 Words Standard QuickDraw II Rectangle giving
- the position of the Move/Change
- window.
- addNewUndo (+389) Byte Currently undocumented.
- revNum (+390) Word Revision number of the version of
- Medley that created this file. For
- files created following this
- standard, use $0100 (for Medley
- 2.0).
- showRulers (+392) Byte Indicates whether the rulers are
- showing.
- windowType (+393) Word The type of window this is. 0 =
- document, 1 = clipboard. When
- creating files, set this to zero.
- auxDictPath (+395) 129 Bytes Class zero GS/OS pathname
- to the auxiliary dictionary file for
- this document. When creating files,
- set this to a null pathname (a
- length byte of zero).
- grayScale (+524) Word Whether or not grayScale mode is
- active. Zero for color, one for
- grayScale.
- printRecordDefined
- (+526) Word Non-zero if a print record is defined.
- This is used because the Printer and
- Port drivers must be loaded before
- calling PrDefault or PrValidate, and
- that means the boot disk must be on
- line. If Medley knows the print
- record is good, it proceeds without
- calling the Print Manager.
- evenPageNumText
- (+528) 48 Bytes The text for even-numbered pages to be
- displayed by the page number.
- oddPageNumText
- (+576) 48 Bytes The text for odd-numbered pages to be
- displayed by the page number.
- pageNumInfo (+624) 32 Words A word for each of the
- pages possible in the file, through
- the absolute maximum of thirty-two.
- affectPageRange(+688) 2 Bytes The range of pages
- affected by the Medley "Change Page
- Numbers" command. The first byte is
- the beginning page; the second byte
- is the ending page.
- pageNumFont (+690) 4 Bytes A Font Manager FontID,
- identifying the font used for the
- page numbers. This is a two-byte
- font family number, followed by a
- one-byte font style and one-byte
- font size.
- startPageNum (+694) Word The page number of the first
- page. This is a zero-based counter;
- page one is represented as zero.
- offsetFromEdge (+696) Word The distance in points that
- the page numbering text appears from
- the edge of the paper.
-
- Note: The following three fields are in Medley 2.0 files, but do not
- exist in Medley 1.0 files. If you are reading a 1.0 file, the
- value of revNum will be $0000. If reading a 1.0 File Object,
- resize it to 2.0 size (including the three fields below) and
- initialize their values to the values given below.
-
- maxNumPages (+698) Word The maximum number of pages in
- this document. When creating new
- files, initialize this to 32 ($20)
- unless condensed (below) is non-
- zero. If condensed is non-zero, you
- really have to hurt yourself to get
- this field right. Below is the
- algorithm Medley uses to calculate
- this field (in something close but
- not exactly related to pseudo-code).
- Please recall that all variables
- relating to the margins (taken from
- the file object) are Fixed.
-
- workHeight := topMrgn + bottomMrgn
- if [condensed is non-zero] then workHeight := workHeight * 2
- workHeight := pageHeight - workHeight
- workHeight := workHeight * [pixels per vertical inch]
- workHeight := workHeight + $0000FFFF
- [this counts a fractional point as a whole point]
- i := HiWord(workHeight) [this gives the integer portion]
- i := i + 3 [accounts for 3-pixel page breaks]
- i := (16384 - 208) / i [gives number of pages in conceptual
- drawing space. Since Medley allows 48-point characters plus
- leading, the tallest a text rectangle may be is 208 pixels. Text
- that does not fit in maxNumPages is kept around in a non-
- displayable, non-editable, non-printable page. Any shortening of
- the document will cause some or all of the previously non-
- displayed text to flow up into the document.]
- i := min(32,i) [32 is the absolute maximum number of pages Medley
- allows due to QuickDraw's conceptual drawing space limitations.]
-
- maxNumPages := i
-
- condensed (+700) Word Indicates whether the document is
- designed to use condensed printing.
- If non-zero, the document is
- designed to use condensed printing.
- When creating files, it is easiest
- not to deal with condensed printing,
- so set this field to zero. However,
- if you wish to create a document
- that Medley may edit and print as
- condensed, you must correctly relate
- this field to the previous one by
- the algorithm given above.
- reserved (+702) 6 Bytes These six bytes should be set
- to zero.
-
-
- The Page Object
-
- Pages are the first-level children of files. There is one page object for
- each page in a document (file object).
-
- rect (+013) 4 Words Standard QuickDraw II rectangle
- giving the boundary rectangle for
- this page.
- wrapDir (+021) Byte The direction of word-wrapping.
- 1 = Down, 2 = across.
- rgn (+022) Long Handle to the region for this page in
- memory. The region is the page
- rectangle less any areas on that
- page. Global areas are not
- subtracted from this region. They
- are subtracted from the page
- rectangle for the global page (page
- zero). On disk, where the page
- region would be written, you can
- write a 10, followed by the
- rectangle for the page. This is a
- rectangular region. The aggregate
- size of the page object on disk must
- include these 10 bytes. This is
- assuming, of course, that there are
- no areas on that page to make the
- page region non-rectangular.
- hideGlobalArt (+026) Byte A non-zero value indicates
- that global art is not displayed on
- this page.
- hideGlobalPageParts
- (+027) Byte A non-zero value indicates that global
- page parts are not displayed on this
- page.
-
- The Paragraph Object
-
- Paragraphs are the children of the file object; they are not the children of
- page objects since a paragraph may be seen on more than one page or page part.
- Paragraph objects are, however, stored on disk immediately following page
- objects and their children. Paragraph objects are first-level objects also.
-
- wrapHere (+013) Word Insertion offset point in
- paragraph data where wrapping should
- continue. For wrapping from
- beginning of paragraph, set this
- field to zero.
- fullWrap (+015) Word Same as wrapHere, but indicates at
- what point miniRect construction or
- reconstruction must continue.
- Again, for full-wrapping of a
- paragraph, set to zero.
- rulerOffset (+017) Word Offset in bytes from beginning
- of paragraph object to indicate
- where the ruler starts. (The ruler
- is just before the character data,
- just after the miniRects.) If there
- is no ruler, then the default ruler
- is used by Medley. (If the
- dataOffset value is the same as the
- rulerOffset, then there is no ruler,
- and the default ruler will be used.)
- The default ruler has tabs at each
- 1/2 inch mark, no indent or
- paragraph indent, and the right
- margin is at maximum.
- dataOffset (+019) Word Offset in bytes from beginning
- of paragraph object to indicate
- where character data starts. If
- there are no miniRects built yet
- (probable if file is being created
- outside Medley) and there is no
- ruler, then this value will be a 32.
- numRects (+021) Word The number of discrete text
- rectangles in this paragraph. When
- creating a file, set fullWrap to
- zero, and numRects to zero, and
- place your character data starting
- at byte 32 of a paragraph object,
- and the rectangles will be built
- when the file is loaded by Medley as
- wrap occurs.
- begInvOffset (+023) Word Offset from the beginning of
- the character data where inverse
- text starts in this paragraph.
- endInvOffset (+025) Word Offset from the beginning of
- the character data where inverse
- text ends in this paragraph.
- topLeading (+027) Byte The number of pixels leading
- above each line in this paragraph.
- botLeading (+028) Byte The number of pixels leading
- below each line in this paragraphs.
- begPgphGap (+029) Byte The number of pixels extra
- leading above this paragraph.
- endPgphGap (+030) Byte The number of pixels extra
- leading below this paragraph.
- flags (+031) Flag Byte Bits 0 and 1 are used to
- indicate justify mode.
- 00 = left justify.
- 01 = right justify.
- 10 = center justify.
- 11 = full justify.
- Bit 7 indicates a page-break after
- this paragraph.
- miniRects (+032) MiniRects Any miniRects, if any, are
- contained here. The number of
- miniRects is given by numRects
- above.
-
- MiniRects have the following format:
-
- miniRect.rect (+000) 4 Words Standard QuickDraw II
- rectangle that is calculated by the
- wordWrap routine to bound a line of
- text.
- mr.begOffset (+008) Word Offset from start of character
- data to the first character this
- miniRect bounds.
- mr.endOffset (+010) Word Offset from start of character
- data to just past the last character
- this miniRect bounds.
-
- A Ruler in the document will be after the miniRects, if there are
- any. The offset to the Ruler is given by rulerOffset. Rulers are
- formatted as follows:
-
- leftPgphMrgn (+000) Byte The left margin for this
- paragraph, in sixteenths of an inch.
- rightPgphMrgn (+001) Byte The right margin for this
- paragraph, in sixteenths of an inch.
- This is an offset from the default
- right margin from Medley's "Set
- margins" command. For example, the
- value 16 represents a right margin
- one inch to the left of the default
- right margin.
- pgphIndent (+002) Byte The indentation for this
- paragraph, in sixteenths of an inch.
- numTabs (+003) Byte The number of tabs in this ruler.
- tabs (+004) Tabs There are numTabs of these.
-
- Tabs are formatted as follows:
-
- tab Flag Word Tabs consist of a high byte of flags
- and low byte of position. The bits
- are assigned as follows:
- Bits 15-12 = Reserved; set to zero.
- Bits 11-10 = Tab Leader style:
- 00 = No leader
- 01 = Leader of dots (.......)
- 10 = Leader of dashes ( - - )
- 11 = Solid Leader (_________)
- Bits 9-8 = Tab Type:
- 00 = Left Tab
- 01 = Right Tab
- 10 = Center Tab
- 11 = Decimal Tab
- Bits 7-0 = Byte value; the
- position of this tab as an
- offset from the left
- margin in sixteenths of an
- inch. A value of sixteen
- indicates a tab one inch
- to the right of the left
- margin.
-
- Following miniRects and rulers is the actual character data for
- this paragraph. This is all Bytes. However, a Byte value of
- $01 through $07 indicates the beginning of a Font Escape. Font
- Escapes indicate changes in style or size of the text, and are
- formatted as follows:
-
- FontEscape (+000) Byte An indication of the type of
- text the following fontID affects:
- 1 = Regular Text
- 2 = Superscript Text
- 3 = Subscript Text
- 4-7 = Reserved; do not use
- fontID (+001) 4 Bytes A Font Manager FontID,
- identifying the font used for the
- page numbers. This is a two-byte
- font family number, followed by a
- one-byte font style and one-byte
- font size.
-
- The text portion of a paragraph always begins with a Font Escape
- and ends with the end-of-paragraph character Byte $A6. This
- makes the minimum size of a paragraph (assuming no miniRects or
- rulers) thirty-eight bytes (32 bytes for the Paragraph Object,
- five bytes for the Font Escape and one byte for the $A6).
-
-
- The Area Object
-
- Area Objects are the children of pages or paragraphs.
-
- type (+013) Byte The type of area this area object
- describes. Possible values are:
- 0 = Null Area
- 1 = Group Area
- 2 = Rectangular Area
- 3 = Round Rectangular Area
- 4 = Oval Area
- 5 = Polygon Area
- select (+014) Byte This value is one if this area is
- selected.
- showBorder (+015) Byte This value is one if the border
- of this area is showing.
- contentType (+016) Byte 0 = Art, 1 = Wrap Down,
- 2 = Wrap Across.
- rgn (+017) Long Handle to the region that describes the
- shape of this area. On disk, this
- region is at the end of this object
- (see the Reading The File section of
- this Note).
- interiorRgn (+021) Long Handle to the regions that
- describes the interior of this area.
- On disk, this region is at the end
- of this object (see the Reading The
- File section of this Note).
- sizingRgn (+025) Long Handle that contains all the
- sizing dots. It is too slow to draw
- them one at a time. Also, detecting
- that the user clicked in a sizing
- dot can be done quickly -- just not
- which one.
- flags (+029) Word Only bit zero of this word is
- significant; if set it indicates
- this area should be printed to
- LaserWriters in gray-scale. All
- other bits of this word should be
- zero.
- reserved (+031) Word Reserved for Milliken. Set to
- zero.
-
- At this point is the description of the area itself. This
- description varies on the type field above:
-
- For rectangles (type = 2):
-
- rect (+033) 4 Words Standard QuickDraw II rectangle
- describing the rectangle for this
- area.
- For round rectangle (type = 3):
-
- rect (+033) 4 Words Standard QuickDraw II rectangle
- describing the boundary rectangle
- for the round rect.
- height (+041) Word The height of the oval portion of
- the rectangle.
- width (+043) Word The width of the oval portion of the
- rectangle.
-
- For ovals (type = 4):
-
- oval (+033) 4 Words A standard QuickDraw II rectangle
- describing the bounding rectangle
- for this oval. The oval drawn is
- the ellipse inscribed in this
- rectangle.
-
- For Polygons (type = 5):
-
- polygon (+033) Bytes A handle to a QuickDraw II
- polygon. This handle may be passed
- to QD Polygon routines. On disk,
- this polygon is appended to the end
- of this object (see the Reading The
- File section on this Note).
-
- These objects are the last items in the area object.
-
- The Art Object
-
- Art Objects are the children of pages, paragraphs or areas.
-
- BBox (+013) 4 Words A standard QuickDraw II rectangle
- representing the bounding box of
- this art object.
- offsetFromRgn (+021) 2 Words Normally zero. The area
- containing an art image can be grown
- and shrunk. The art within it is
- not clipped to the bounding
- rectangle of the area until the user
- deselects the area. (If it is saved
- to disk while selected, then it is
- saved unclipped). This allows the
- user to experiment with different
- shapes without clipping the drawing
- within. If the drawing is to the
- left of the left edge of the area,
- or is above the top edge, then this
- offset indicates by how much.
- artImage (+025) Bytes The actual bitmap of the art
- image.
-
- The Document Dictionary Object
-
- The Document Dictionary Object is the very last child of the file object, and
- contains all the words the spelling checker should ignore even though they are
- not in the main dictionary.
-
- count (+013) Word The number of word entries in this
- dictionary object.
- wordList (+015) Word Entries List of dictionary word
- entries.
-
- The format of word entries is as follows:
-
- recordLength (+000) Byte The length of this record.
- replaceFlag (+001) Byte Reserved, set to zero.
- newWord (+002) C String The word in question. This
- word should be counted as spelled
- correctly, and is not in the Main or
- Auxiliary Dictionary.
-
- The length of a record is the length of string plus three bytes
- (one for recordLength, one for replaceFlag, and a zero termination
- byte).
-
-
- Reading the File
-
- When reading a Medley file, objects with regions or polygons will have to be
- treated specially, since the handles in the objects are invalid and the
- regions or polygons actually follow the object in the disk file.
-
- A sequence for reconstructing Medley files in memory is as follows:
-
- 1. Open the file, or set the mark to zero on an open file.
- 2. Start with a handle that is 13 ($0D) bytes long. Pass this
- handle to the routine starting in step three.
- 3. Save the handle passed to this routine, and read four bytes
- from disk. This Long is the total size of an object, including
- any regions or polygons appended.
- 4. Read the 13-byte object header into the handle passed to this
- routine. The endData field of the header gives the size of the
- object, minus any associated regions or polygons. Resize the
- object's handle (the handle passed to you) to this size.
- 5. Read the rest of the object (endData - 13 bytes) into the
- object's handle.
- 6. Save the value of numChildren in a local variable and set the
- numChildren field in the object header to zero. The field in
- the header represents the number of children read from disk;
- setting this to zero properly indicates that you haven't read
- any of the children yet.
- 7. Look at the object type field. If the object is a file, area,
- or page object, it may have a region associated with it. If the
- object is an area object, it may also have a polygon associated
- with it (if the area type field indicates this is so). You can
- tell if the object has any appended structures by comparing the
- total object size (read in step three) with the endData field
- (read in step four); if an object has no appended structures,
- the two values will be the same.
-
- If there are structures appended to the object, first zero all
- the handles to the regions inside the object. This allows
- elegant error recovery if an error occurs while reading the
- region or polygon. When the handles are zeroed, read the next
- two bytes from the disk. This Word is the size of the region or
- polygon in bytes. Create a handle of that size, place it in the
- object's field for this handle, and place the size Word in the
- first two bytes of the new handle. Now read the object from
- disk into the new handle starting at the beginning +002 (past
- the size Word).
-
- Continue in this fashion until all appended regions or polygons
- have been read from disk. Any appended structures will be
- stored in the same order as their handles occur in the object.
-
- Note: By zeroing the handles before reading the objects, you
- can return from this function with an error, and the
- calling routine will be able to dispose of all handles
- that were actually created. The calling routine will know
- if a handle was actually created or not by examining the
- handle field in the object; NIL handles were not created.
-
- 8. Execute a loop for the old number of children (0 to
- oldNumChildren-1):
- 9. Create an object that is 13 ($0D) bytes long. Add this handle
- to the end of the parent object that was last read. Increment
- the number of children. You have just added a child into the
- child table for an object.
- 10. Call the recursive subroutine beginning in step three, passing
- it the handle you just created. If it returns an error, return
- the error. This gets you out of the recursion with the correct
- error, no matter how many levels deep you are.
- 11. Keep looping until out of children to read. The EOF condition
- does not have to be checked, since you will run out of children
- when you reach the end of the file. If an EOF is reached before
- you read all the children, you did something wrong.
- 12. Return no error--the file was successfully read.
- 13. When done with all this, you will return to the code just
- beyond step two, where you first called the recursive subroutine
- at step three. If an error is returned, dispose of all the
- handles created by the recursive function. Even if the file
- read is aborted, the tree is complete for as much as was read.
- (This is why the numChildren field is incremented as you read
- the file.) An alternate way to handle this is to use a
- different userID for the handles created when reading the file;
- this allows you to dispose of all of them with one DisposeAll
- call.
- 14. Close the file if you opened it, or reset the mark to its
- previous position if it was already open.
-
- The entire file does not have to be read from disk. By using the size field,
- you can skip to the next object in the file. Using this technique, you can
- scan the file for whatever it is that interests you.
-
- Note: You may have noticed that objects successfully created in
- memory will have a table of handles to children at the end.
- Objects on disk will not have these handles, since the handles on
- disk are meaningless. The child handle table is reconstructed as
- the file is loaded into memory.
-
-
- Object Ordering
-
- The file object is the first you will encounter in a Medley file. Its
- children are ordered as follows:
-
- Page Object--Page #0. This is the global page object, containing all global
- areas.
- Page Object--Page #1. This is the page object for page #1; it must exist.
-
- Other objects are optional, but will appear in the following order:
-
- Page #2 through Page #n
- Paragraph #1 through Paragraph #n
- Dictionary Object
-
-
- Some Example Structures
-
- Medley was written mostly in C. Below are some structures relevant to C
- programs reading Medley files. Descriptions of the fields may be found
- earlier in this Note.
-
- #define NULLOBJ 0 /* Object type assignments. */
- #define ROOTOBJ 1 /* These are used in the deskObj 'types' field. */
- #define FILEOBJ 2
- #define PAGEOBJ 3
- #define PGPHOBJ 4
- #define AREAOBJ 5
- #define ARTOBJ 6
- #define DOCDICTOBJ 10
-
- #define AREANULL 0 /* Area object sub-type assignments. */
- #define AREAGROUP 1 /* These are used in the areaObj 'types' field. */
- #define AREARECT 2
- #define AREARRECT 3
- #define AREAOVAL 4
- #define AREAPOLY 5
-
-
- #define medleyMainType 0x54
- #define medleyAuxType 0xDD3E
- #define medleyInfo 1
- #define auxDictType 2
-
-
- #define ARTCONTENT 0 /* These are used in the 'contentType' field of
- area objects.*/
- #define WWDOWN 1
- #define WWACROSS 2
- #define LWGRAYSCALE 0x0001
-
-
- #define SAMEESC 0 /* These are used in paragraph objects. */
- #define FONTESC 1
- #define SUPERESC 2
- #define SUBESC 3
- #define ESCAPES 7
-
-
- #define SIZEFONTESC 5 /* More paragraph equates. */
- #define ENDPGPHCHR 0xA6
- #define TABCHR 9
- #define SOFTHYPHEN 30
- #define STICKYSPACE 31
-
-
- #define PAGEBREAK 0x80 /* These are used in the pgphObj 'flags' field. */
- #define LEFTJUST 0x00
- #define RIGHTJUST 0x01
- #define CENTERJUST 0x02
- #define FULLJUST 0x03
- #define JUSTTYPES 0x03
-
- #define LEFTTAB 0x00 /* These are used in the ruler field of paragraph
- objects. */
- #define RIGHTTAB 0x01
- #define CENTERTAB 0x02
- #define DECIMALTAB 0x03
- #define TABTYPES 0x03
- #define NOLEADER 0x00
- #define DOTSLEADER 0x01
- #define DASHESLEADER 0x02
- #define SOLIDLEADER 0x03
-
- typedef struct Ruler {
- unsigned char leftPgphMrgn;
- unsigned char rightPgphMrgn;
- unsigned char pgphIndent;
- unsigned char numTabs;
- unsigned int tab[];
- } Ruler;
-
- #define NEWREVNUM 0x0100
-
-
- typedef union URect {
- Rect rect;
- struct {
- long p1;
- long p2;
- } point;
- struct {
- Point p1;
- Point p2;
- } ele;
- } URect;
-
- typedef union UPoint {
- Point ele;
- long point;
- } UPoint;
-
- typedef struct region {
- unsigned int size;
- union URect BBox;
- int data[];
- } region;
-
- typedef struct polygon {
- int size;
- union URect BBox;
- union UPoint point[];
- } polygon;
-
- typedef union ourFontID {
- unsigned long fid;
- struct {
- unsigned int famNum;
- char fontStyle;
- char fontSize;
- } f;
- } ourFontID;
-
- struct deskObj {
- char type; $00
- unsigned int numChildren; $01
- unsigned long endData; $03
- unsigned long reserved; $07
- unsigned int objRefNum; $0B
- $0D
-
- union d {
- data[]; /* Plain label object access field. */
-
- struct file { /* Level 1 objects are files. */
- union URect rect; /* $0D */
- char pathName[129]; /* $15 */
- char saved; /* $96 */
- GrafPortPtr windowPtr; /* $97 */
- char windowNameIndx; /* $9B */
- long windowOrigin; /* $9C */
- long windowSize; /* $A0 */
- long COrigin; /* $A4 */
- struct deskObj **editHndl; /* $A8 */
- unsigned int editOffset; /* $AC */
- union URect cursor; /* $AE */
- char showAllBorders; /* $B6 */
- union URect updateRect; /* $B7 */
- unsigned long topMrgn; /* $BF */
- unsigned long bottomMrgn; /* $C3 */
- unsigned long leftMrgn; /* $C7 */
- unsigned long rightMrgn; /* $CB */
- unsigned long gutterMrgn; /* $CF */
- unsigned long pageWidth; /* $D3 */
- unsigned long pageHeight; /* $D7 */
- int selectPage; /* $DB */
- int numSelected; /* $DD */
- int sizingDot; /* $DF */
- int effectivePage; /* $E1 */
- PrRec printRecord; /* $E3 */
- int interruptMode; /* $16F */
- char editScroll; /* $171 */
- struct deskObj **firstHndl; /* $172 */
- int firstMrn; /* $176 */
- unsigned int selectMode; /* $178 */
- char showPgphMarks; /* $17A */
- char showSpaces; /* $17B */
- char showMoveChangeInfo; /* $17C */
- union URect moveChangeInfoRect; /* $17D */
- char addNewUndo; /* $185 */
- unsigned int revNum; /* $186 */
- char showRulers; /* $188 */
- unsigned int windowType; /* $189 */
- char auxDictPathname[129]; /* $18B */
- unsigned int grayScale; /* $20C */
- unsigned int printRecordDefined; /* $20E */
- char evenPageNumText[48]; /* $210 */
- char oddPageNumText[48]; /* $240 */
- unsigned int pageNumInfo[MAXNUMPAGES];/* $270 */
- unsigned int affectPageRange; /* $2B0 */
- ourFontID pageNumFont; /* $2B2 */
- unsigned int startPageNum; /* $2B6 */
- unsigned int offsetFromEdge; /* $2B8 */
- unsigned int maxNumPages; /* $2BA */
- unsigned int condensed; /* $2BC */
- char reserved[6]; /* $2BE */
- } file; /* $2C4 */
-
- struct page {
- union URect rect; /* $0D */
- char wrapDir; /* $15 */
- region **rgn; /* $16 */
- char hideGlobalArt; /* $1A */
- char hideGlobalPageParts; /* $1B */
- } page; /* $1C */
-
- struct pgph { /* Must be level 2 or greater. */
- unsigned int wrapHere; /* $0D */
- unsigned int fullWrap; /* $0F */
- unsigned int rulerOffset; /* $11 */
- unsigned int dataOffset; /* $13 */
- unsigned int numRects; /* $15 */
- unsigned int begInvOffset; /* $17 */
- unsigned int endInvOffset; /* $19 */
- char topLeading; /* $1B */
- char botLeading; /* $1C */
- char begPgphGap; /* $1D */
- char endPgphGap; /* $1E */
- char flags; /* $1F */
- struct miniRect { /* $20 */
- union URect rect;
- unsigned int begOffset;
- unsigned int endOffset;
- } miniRect[];
- /* Ruler goes here if there is a custom ruler for this paragraph.*/
- /* Text starts after the ruler. Text always
- starts with a fontEsc. A fontEsc is 5 bytes,
- a typeByte followed by the fontID. Text
- always ends with end-of-pgph chr. */
- } pgph; /* $20 */
-
- struct area {
- char type; /* $0D */
- char select; /* $0E */
- char showBorder; /* $0F */
- char contentType; /* $10 */
- region **rgn; /* $11 */
- region **interiorRgn; /* $15 */
- region **sizingRgn; /* $19 */
- unsigned int flags; /* $1D */
- unsigned int reserved; /* $1F */
- union obj {
- union URect rect; /* $21 */
- struct rrect {
- union URect rect; /* $21 */
- int height; /* $29 */
- int width; /* $2B */
- } rrect;
- union URect oval; /* $21 */
- polygon **poly; /* $21 */
- } obj;
- } area; /* $2D */
-
- struct art {
- union URect BBox; /* $0D */
- union UPoint offsetFromRgn; /* $15 */
- char artImage[]; /* $19 */
- } art;
-
- struct docDict {
- unsigned int count; /* $0D */
- char wordList[] /* $0F */
- } docDict; /* $0F */
-
- } d;
- };